package jmine.tec.sync.web.pages;

import static jmine.tec.web.pages.HelpTextMessages.CONSULTA_SYNC_ERRO;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import jmine.tec.report.impl.table.ReportTableBuilder;
import jmine.tec.sync.DatabaseSynchronizationListener;
import jmine.tec.sync.dao.SynchronizationErrorEntityDAO;
import jmine.tec.sync.domain.SynchronizationErrorEntity;
import jmine.tec.sync.domain.enumx.SynchronizationOperationType;
import jmine.tec.web.wicket.component.command.button.ButtonCommand;
import jmine.tec.web.wicket.component.command.button.SingleEntityExecutionButton;
import jmine.tec.web.wicket.pages.form.ExecutePage;
import jmine.tec.web.wicket.upperCase.field.NoUpperCaseTextFieldImpl;

import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.spring.injection.annot.SpringBean;

import bancosys.tec.exception.MessageCreator;
import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BaseDAOFactory;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.security.annotation.Secure;
import bancosys.tec.security.authorization.UrlPermission;

/**
 * Tela que mostra erros sincronização e dispara resincronização
 * 
 * @author gabriel.silva
 */
@Secure(id = "URL_EXEC_SYNC_ERRO", permissionType = UrlPermission.class)
public class SyncErrorPage extends ExecutePage<SynchronizationErrorEntity, SynchronizationErrorEntity> {

    @SpringBean
    private DatabaseSynchronizationListener listener;

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addResultTableColumns(ReportTableBuilder<SynchronizationErrorEntity> table) {
        table.addStringColumn("entityClass", "Classe", "entityClass");
        table.addNumberColumn("remoteEntityId", "Id Remoto", "remoteEntityId", 0);
        table.addStringColumn("source", "Origem", "source");
        table.addStringColumn("operationType", "Tipo de Operação", "operationType");
        table.addStringColumn("message", "Mensagem", "message");

    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void addSearchFields(WebMarkupContainer container) {
        container.add(new NoUpperCaseTextFieldImpl("entityClass"));
        container.add(this.createTextField("remoteEntityId"));
        container.add(this.createTextField("source"));
        container.add(this.createDropDown("operationType", Arrays.asList(SynchronizationOperationType.values())));

    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected SynchronizationErrorEntity createModel() {
        BaseDAO<SynchronizationErrorEntity> dao = this.daoFactoryRef.get().getGenericDAO(SynchronizationErrorEntity.class);
        return dao.createBean();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected MessageCreator getHelpTextCreator() {
        return CONSULTA_SYNC_ERRO;
    }

    /**
     * {@inheritDoc}
     */
    public List<SynchronizationErrorEntity> search(BaseDAOFactory daoFactory) {
        SynchronizationErrorEntityDAO dao = daoFactory.getDAOByClass(SynchronizationErrorEntityDAO.class);
        SynchronizationErrorEntity model = this.getModel();
        return dao.findByEntityClassRemoteIdSourceType(model.getEntityClass(), model.getRemoteEntityId(), model.getSource(), model
                .getOperationType());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<ButtonCommand> getPageCommands() {
        List<ButtonCommand> pageCommands = super.getPageCommands();

        pageCommands.add(new SingleEntityExecutionButton<SynchronizationErrorEntity>() {

            /**
             * {@inheritDoc}
             */
            @Override
            public String getLabel() {
                return "Executar";
            }

            /**
             * {@inheritDoc}
             */
            @Override
            protected void doExecute(SynchronizationErrorEntity entity) {
                SyncErrorPage.this.getListener().setSource(entity.getSource());
                if (entity.getOperationType().compareTo(SynchronizationOperationType.UPDATE) == 0) {
                    SyncErrorPage.this.getListener().onModification(new String[]{ entity.getEntityClass() }, entity.getRemoteEntityId(),
                            entity.getEntityName());
                    entity.getPersister().remove();
                } else {
                    SyncErrorPage.this.getListener().entityDeleted(new String[]{ entity.getEntityClass() }, entity.getRemoteEntityId(),
                            entity.getEntityName());
                    entity.getPersister().remove();
                }
            }

            /**
             * {@inheritDoc}
             */
            @Override
            protected Set<Serializable> getSelected() {
                return SyncErrorPage.this.getSelectedItens();
            }

            /**
             * {@inheritDoc}
             */
            @Override
            protected SynchronizationErrorEntity loadEntity(Serializable entityId) throws BeanNotFoundException {
                return SyncErrorPage.this.loadEntity(entityId);
            }
        });

        return pageCommands;
    }

    /**
     * @param listener the listener to set
     */
    public void setListener(DatabaseSynchronizationListener listener) {
        this.listener = listener;
    }

    /**
     * @return the listener
     */
    public DatabaseSynchronizationListener getListener() {
        return this.listener;
    }
}
